package com.hb.config;

import org.apache.commons.dbcp.BasicDataSource;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Profile;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.jdbc.core.namedparam.NamedParameterJdbcTemplate;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseBuilder;
import org.springframework.jdbc.datasource.embedded.EmbeddedDatabaseType;
import org.springframework.jndi.JndiObjectFactoryBean;

import javax.sql.DataSource;

@Configuration
public class SpringJavaConfig {
    /**
     * 如果想使用 Java 配置的话，那我们可以借助 JndiObjectFactoryBean 从 JNDI 中查找 DataSource
     * @return
     */
    @Profile("production")  // 生产环境的数据源
    @Bean
    public JndiObjectFactoryBean dataSource() {
        JndiObjectFactoryBean jndiObjectFactoryBean = new JndiObjectFactoryBean();
        jndiObjectFactoryBean.setJndiName("jdbc/SpittrDS");
        jndiObjectFactoryBean.setResourceRef(true);
        jndiObjectFactoryBean.setProxyInterface(DataSource.class);
        return jndiObjectFactoryBean;
    }

    /**
     * Java 配置形式的 DBCP BasicDataSource 连接池
     * 其中前四个属性是配置 BasicDataSource 所必须的
     * @return
     */
    @Profile("qa")  // QA 数据源
    @Bean
    public BasicDataSource dataSource1() {
        BasicDataSource ds = new BasicDataSource();
        // 属性 driverClassName 指定了 JDBC 驱动类的全限定类名。在这里我们配置的是 H2 数据库的数据源
        ds.setDriverClassName("org.h2.Driver");
        // 属性 url 用于设置数据库的 JDBC URL
        ds.setUrl("jdbc:h2:tcp://localhost/~/spitter");
        ds.setUsername("sa");
        ds.setPassword("");
        ds.setInitialSize(5);
        ds.setMaxActive(10);
        return ds;
    }

    /**
     * 配置 DriverManagerDataSource
     * @return
     */
    @Bean
    public DataSource dataSource2() {
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("org.h2.Driver");
        ds.setUrl("jdbc:h2:tcp://localhost/~/spitter");
        ds.setUsername("sa");
        ds.setPassword("");
        return ds;
    }

    /**
     * 配置嵌入式数据库
     * @return
     */
    @Profile("development") // 开发数据源
    @Bean
    public DataSource dataSource3() {
        return new EmbeddedDatabaseBuilder()
                .setType(EmbeddedDatabaseType.H2)
                .addScript("classpath:/db/schema.sql")
                .build();
    }

    /**
     * 在 Spring 中配置 JdbcTemplate 只需要为其设置 DataSource 就可以了
     * @param dataSource
     * @return
     */
    @Bean
    public JdbcTemplate jdbcTemplate(DataSource dataSource) {
        return new JdbcTemplate(dataSource);
    }

    /**
     * NamedParameterJdbcTemplate 是一个特殊的 JDBC 模板类，它支持使用命名参数。在 Spring 中，NamedParameterJdbcTemplate的声明方式与常规
     * 的 JdbcTemplate 几乎完全相同。
     * @param dataSource
     * @return
     */
    @Bean
    public NamedParameterJdbcTemplate jdbcTemplate1(DataSource dataSource) {
        return new NamedParameterJdbcTemplate(dataSource);
    }
}
